#ifndef VAGDI_H
#define VAGDI_H

#include <QObject>
#include <QString>
#include <windows.h>
#include <QThread>
#include "AGDI.H"
#include "BOM.H"
#include "COLLECT.H"
#include "COMTYP.H"

class VAGDI : public QObject
{
	Q_OBJECT
public:
    VAGDI(QObject *parent = nullptr);
    ~VAGDI();

    void load_library();
    void release_library();
    int AG_init(QString path);
    int AG_GoStep();
    int ag_go_breakpoint();
    int EnumUv351();
    int DllUv3Cap();
    void ag_step_out();
    void ag_step_over();
    void ag_step_into();
    void ag_stop();
    void ag_stop_run();

    HWND _main_handle = 0;
    UL32 _pc = 0;
    bool _is_debug = false;

public slots:
    void slot_set_breakpoint(int addr);
    void slot_kill_breakpoint(int addr);
    void slot_enable_breakpoint(int addr);
    void slot_disable_breakpoint(int addr);
    void slot_start(QString path);
    void slot_stop();
    void slot_ag_step_out();
    void slot_ag_step_into();
    void slot_ag_step_over();
	
signals:
    void signal_runing(bool runing);
    void signal_ag_update_pc(int addr);

private:
    HMODULE hMod = 0;
    typedef U32(*AG_AllReg_typedef) (U16 nCode, void *pR);
    typedef U32(*AG_BpInfo_typedef) (U16 nCode, void *vp);
    typedef AG_BP  *(*AG_BreakFunc_typedef) (U16 nCode, U16 n1, GADR *pA, AG_BP *pB);
    typedef U32(*AG_GoStep_typedef) (U16 nCode, U32 nSteps, GADR *pA);
    typedef U32(*AG_HistFunc_typedef) (U32 nCode, I32 indx, I32 dir, void *vp);
    typedef U32(*AG_Init_typedef) (U16 nCode, void *vp);
    typedef U32(*AG_MemAcc_typedef) (U16 nCode, UC8 *pB, GADR *pA, UL32 nMany);
    typedef U32(*AG_MemAtt_typedef) (U16 nCode, UL32 nAttr, GADR *pA);
    typedef U32(*AG_RegAcc_typedef) (U16 nCode, U32 nReg, GVAL *pV);
    typedef U32(*AG_Serial_typedef) (U16 nCode, U32 nSerNo, U32 nMany, void *vp);
    typedef int(*DllUv3Cap_typedef)(DWORD nCode, void *p);
    typedef int(*EnumUv351_typedef)(void *p, DWORD nCode);

    AG_AllReg_typedef AG_AllReg_hook;
    AG_BpInfo_typedef AG_BpInfo_hook;
    AG_BreakFunc_typedef AG_BreakFunc_hook;
    AG_GoStep_typedef AG_GoStep_hook;
    AG_HistFunc_typedef AG_HistFunc_hook;
    AG_Init_typedef AG_Init_hook;
    AG_MemAcc_typedef AG_MemAcc_hook;
    AG_MemAtt_typedef AG_MemAtt_hook;
    AG_RegAcc_typedef AG_RegAcc_hook;
    AG_Serial_typedef AG_Serial_hook;
    DllUv3Cap_typedef DllUv3Cap_hook;
    EnumUv351_typedef EnumUv351_hook;
    char* new_string(const char* init_string, int size);
    void write_proc(QString path);
    void set_breakpoint(int addr);
    bool kill_breakpoint(int addr);
    void enable_breakpoint(int addr);
    void disable_breakpoint(int addr);
    AG_BP * get_bp_last();

    int _count;
    pCBF callback;
    AG_BP *_bp_head = nullptr;
    unsigned char _ret_symbol[0xFFFF] = {0};
    unsigned char _call_symbol[0xFFFF] = {0};
};

#endif // VAGDI_H
